package com.deram.ctin.serv.third.api.impl;

import com.deram.ctin.common.error.BusinessException;
import com.deram.ctin.common.utils.HttpServletUtils;
import com.deram.ctin.common.utils.ValidateUtils;
import com.deram.ctin.serv.third.api.SmsApi;
import com.deram.ctin.serv.third.prop.SmsProp;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

@RestController
public class SmsApiImpl implements SmsApi {

    private static final Logger logger = LoggerFactory.getLogger(SmsApiImpl.class);

    private static final String CODE_SUCCESS = "0";

    @Autowired
    private SmsProp smsProp;

    @Override
    public void send(String mobile, String content) {
        ValidateUtils.isMobile(mobile);
        ValidateUtils.notEmpty(content, smsProp.getContentMaxLength(), "内容");

        // 检查白名单
        checkWhiteList(Lists.newArrayList(mobile));

        Map<String, Object> paramMap = Maps.newHashMap();
        paramMap.put("un", smsProp.getAccount());
        paramMap.put("pw", smsProp.getPswd());
        paramMap.put("phone", mobile);
        paramMap.put("msg", smsProp.getAutograph() + content);
        paramMap.put("rd", "1");

        String result = HttpServletUtils.httpPostContent(smsProp.getSingleUrl(), paramMap);
        Map<String, Object> resultMap = parseResult(result);
        boolean state = (Boolean) resultMap.get("state");
        if(!state){
            throw new BusinessException((String) resultMap.get("returnMsg"));
        }
    }

    private Map<String, Object> parseResult(String resultStr){
        logger.info("短信服务商返回结果：{}", resultStr);
        Map<String, Object> resultMap = Maps.newHashMap();
        resultMap.put("state", false);
        if(StringUtils.isBlank(resultStr)){
            return resultMap;
        }
        String[] resultArr = StringUtils.split(resultStr, "\n");
        if(ArrayUtils.isEmpty(resultArr)){
            return resultMap;
        }
        String[] stateArr = StringUtils.split(resultArr[0], ",");
        if(ArrayUtils.isEmpty(stateArr) && stateArr.length < 2){
            return resultMap;
        }
        Boolean state = CODE_SUCCESS.equals(stateArr[1]);
        if(!state){
            resultMap.put("returnMsg", findErrorMsg(stateArr[1]));
            return resultMap;
        }
        resultMap.put("state", state);
        resultMap.put("msgId", resultArr[1]);
        return resultMap;
    }

    private void checkWhiteList(List<String> mobileList){
        if(!smsProp.getWhiteListEnabled() || CollectionUtils.isEmpty(smsProp.getWhiteList())){
            return;
        }
        for (String mobile : mobileList) {
            if(!smsProp.getWhiteList().contains(mobile)){
                throw new BusinessException(mobile + "不在白名单中，无法发送");
            }
        }
    }

    private String findErrorMsg(String errorCode) {
        String errorMsg = "";
        switch (errorCode) {
            case "0": errorMsg = errorCode + ":提交成功"; break;
            case "101": errorMsg = errorCode + ":无此用户"; break;
            case "102": errorMsg = errorCode + ":密码错"; break;
            case "103": errorMsg = errorCode + ":提交过快（提交速度超过流速限制）"; break;
            case "104": errorMsg = errorCode + ":系统忙（因平台侧原因，暂时无法处理提交的短信）"; break;
            case "105": errorMsg = errorCode + ":敏感短信（短信内容包含敏感词）"; break;
            case "106": errorMsg = errorCode + ":消息长度错（>536或<=0）"; break;
            case "107": errorMsg = errorCode + ":包含错误的手机号码"; break;
            case "108": errorMsg = errorCode + ":手机号码个数错（群发>50000或<=0）"; break;
            case "109": errorMsg = errorCode + ":无发送额度（该用户可用短信数已使用完）"; break;
            case "110": errorMsg = errorCode + ":不在发送时间内"; break;
            case "113": errorMsg = errorCode + ":extno格式错（非数字或者长度不对）"; break;
            case "116": errorMsg = errorCode + ":签名不合法或未带签名（用户必须带签名的前提下）"; break;
            case "117": errorMsg = errorCode + ":IP地址认证错,请求调用的IP地址不是系统登记的IP地址"; break;
            case "118": errorMsg = errorCode + ":用户没有相应的发送权限（账号被禁止发送）"; break;
            case "119": errorMsg = errorCode + ":用户已过期"; break;
            case "120": errorMsg = errorCode + ":违反放盗用策略(日发限制) --自定义添加"; break;
            case "121": errorMsg = errorCode + ":必填参数。是否需要状态报告，取值true或false"; break;
            case "122": errorMsg = errorCode + ":5分钟内相同账号提交相同消息内容过多"; break;
            case "123": errorMsg = errorCode + ":发送类型错误"; break;
            case "124": errorMsg = errorCode + ":白模板匹配错误"; break;
            case "125": errorMsg = errorCode + ":匹配驳回模板，提交失败"; break;
            case "126": errorMsg = errorCode + ":审核通过模板匹配错误"; break;
            default: errorMsg = errorCode + ":未知"; break;
        }
        return errorMsg;
    }
}
